unit coba1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;


type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    ListBox1: TListBox;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure GrayscaleBitmap(ABitmap: TBitmap);
    function CheckNodeState(iXPos, iYPos : Integer) : Integer;
    procedure CheckNama();

  private
    { Private declarations }
  public
    { Public declarations }
  end;

  PRGBTripleArray = ^TRGBTripleArray;
  TRGBTripleArray = array[0..4095] of TRGBTriple;

var
  Form1: TForm1;
  iYmarkFinal : Integer;   //deklarasi variable global
  iXmarkFinal : Integer;
  Pixels: PRGBTripleArray;
  Bitmap: TBitmap;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
  Bitmap: TBitmap;
  Pixels: PRGBTripleArray;
begin
  Bitmap := TBitmap.Create;
  try
    Bitmap.Width := 3;
    Bitmap.Height := 2;
    Bitmap.PixelFormat := pf24bit;
    // get pointer to the second row's raw data
    Pixels := Bitmap.ScanLine[1];
    // iterate our row pixel data array in a whole width
    for I := 0 to Bitmap.Width - 1 do
    begin
      Pixels[I].rgbtBlue := 0;
      Pixels[I].rgbtGreen := 0;
      Pixels[I].rgbtRed := 0;
    end;
    Bitmap.SaveToFile('D:\Image.bmp');
  finally
    Bitmap.Free;
  end;
end;

procedure TForm1.GrayscaleBitmap(ABitmap: TBitmap);
var
  X: Integer;
  Y: Integer;
  Gray: Byte;
  sData : String;
  iCount : Integer;
  iYmark : Integer;
  iXmark : Integer;
begin
    iCount := 0;
    iYmark := 0;
    iXmark := 0;
    iYmarkFinal := 0;
    iXmarkFinal := 0;
    //Showmessage (IntToStr(ABitmap.Height)+'-'+IntToStr(ABitmap.Width));
  // iterate bitmap from top to bottom to get access to each row's raw data
  for Y := 0 to ABitmap.Height - 1 do
  begin
    // get pointer to the currently iterated row's raw data
    Pixels := ABitmap.ScanLine[Y];
    // iterate the row's pixels from left to right in the whole bitmap width
    for X := 0 to ABitmap.Width - 1 do
    begin
      // calculate luminance for the current pixel by the mentioned formula
      Gray := Round((0.299 * Pixels[X].rgbtRed) +
        (0.587 * Pixels[X].rgbtGreen) + (0.114 * Pixels[X].rgbtBlue));
      // and assign the luminance to each color component of the current pixel
      sData := sData + '-' + Inttostr(Pixels[X].rgbtRed);
      if (Pixels[X].rgbtRed < 200)  then  //bukan berwarna putih
      begin
        if(iCount = 0) then
        begin
          iXmark := X;
          iYmark := Y;
        end;
        iCount := iCount + 1;
        if(iCount > 40) then
        begin
            //Showmessage ('Marking start adalah : baris pixel ' + inttostr(iYmark) + ' dan kolom pixel ' + inttostr(iXmark));
            iYmarkFinal := iYmark;
            iXmarkFinal := iXmark;
            exit; //keluar dari fungsi
        end;
      end
      else
        iCount := 0;
      Pixels[X].rgbtRed := Gray;
      Pixels[X].rgbtGreen := Gray;
      Pixels[X].rgbtBlue := Gray;
    end;
    ListBox1.Items.Add(sData);
    sData := '';
  end;
end;
procedure SetHorizontalScrollBar(lb : TListBox) ;
var
  j, MaxWidth: integer;
begin
  MaxWidth := 0;
  for j := 0 to lb.Items.Count - 1 do
  if MaxWidth < lb.Canvas.TextWidth(lb.Items[j]) then
    MaxWidth := lb.Canvas.TextWidth(lb.Items[j]) ;

  SendMessage(lb.Handle,
              LB_SETHORIZONTALEXTENT,
              MaxWidth + 5, 0) ;
end;

procedure TForm1.Button2Click(Sender: TObject);
//var
begin
  Bitmap := TBitmap.Create;
  try
  //    Bitmap.LoadFromFile('d:\ColorImage.bmp');
    Bitmap.LoadFromFile('d:\img004.bmp');
    if Bitmap.PixelFormat <> pf24bit then
      raise Exception.Create('Incorrect bit depth, bitmap must be 24-bit!');
    GrayscaleBitmap(Bitmap);
    SetHorizontalScrollBar(ListBox1) ; 
    Bitmap.SaveToFile('d:\GrayscaleImage.bmp');
    //Showmessage (inttostr(CheckNodeState(98,878)));
    //Showmessage (inttostr(CheckNodeState(98,1216)));
    CheckNama();
  finally
    Bitmap.Free;
  end;
end;
function TForm1.CheckNodeState(iXPos, iYPos : Integer) : Integer;
var
    iXRealPos, iYRealPos : Integer;
    iCount,x,y : Integer;
begin
    iCount := 0;
    iXRealPos := iXMarkFinal + iXPos;
    iYRealPos := iYMarkFinal + iYPos;
    //showmessage (inttostr(iXRealPos) + '+' + inttostr(iYRealPos));
    for y := iYRealPos to (iYRealPos + 13 - 1) do
    begin
        Pixels := Bitmap.ScanLine[y];
        for x := iXRealPos to (iXRealPos + 7 - 1) do
        begin
            //showmessage ('hasil : '+inttostr(Pixels[x].rgbtRed));
            if (Pixels[x].rgbtRed < 200) then
            begin
                iCount := iCount + 1;
            end;
        end;
    end;
    //showmessage (inttostr(iCount));
    if iCount > (7*14)-40 then
        Result := 1
    else 
        Result := 0;
        
end;
procedure TForm1.CheckNama();
var
    iXStartNama, iYStartNama : Integer;
    iConstRow, iConstCol : Integer;
    i,j : integer;
    sNama : String;
begin
    sNama := '';
    iXStartNama := 98; //titik pertama pengecekan nama
    iYStartNama := 878;
    iConstRow := 43;
    iConstCol := 49;
    for i := 1 to 20 do
    begin
        for j := 1 to 26 do
        begin
            if (CheckNodeState(iXStartNama+iConstCol*(i-1), iYStartNama+iConstRow*(j-1)) = 1) then
                break;
        end;
        if (j = 26) then
            j := -32;
        
        sNama := sNama + chr(j+64); // ascii 64 itu sebelum huruf 'A'  
    end;
    showmessage(sNama);  
end;
end.
